import React, { memo, useCallback, useEffect, useImperativeHandle, useRef, useState, useMemo, useContext } from 'react';
import cn from 'classnames';
import { message, Popconfirm, Spin } from 'antd';
import useUploadOss from '@/hooks/useUploadOss';
import usePreventUnload from '@/hooks/usePreventUnload';
import AudioRecorder from '@/utils/recorder';
import { RecorderStateContext } from '../../Communicate/Edit';
import styles from './index.less';

let timer; // 每个一秒设置录音时间的定时器
const renderButton = ({
    start,
    finished,
    time = '00:00:00',
    handleAudioStart,
    handleAudioStop,
    onBeforeStart,
    recordStatusMsg,
    move,
    recorderStateContext
}) => {
    if (recordStatusMsg) {
        return (
            <>
                <span className={styles.isRecording}>
                    <i className={cn('iconfont iconrecordIcon', styles.startAudioIcon)} /> {recordStatusMsg}
                </span>
            </>
        );
    }

    if (start) {
        return (
            <>
                <Popconfirm
                    title={
                        <div>
                            <div>确定要停止录制?</div>
                            <div className={styles.recordHint}>录音一旦停止不可再次开启</div>
                        </div>
                    }
                    onConfirm={handleAudioStop}
                    okText="停止"
                    getPopupContainer={trigger => (move ? document.body : trigger.parentNode.parentNode)}
                    autoAdjustOverflow
                >
                    <div className={styles.audioButtonContent}>
                        <i className={cn('iconfont iconstop_record_Icon', styles.startAudioingIcon)} />
                        <span style={{ fontSize: 16 }}>{time}</span>
                    </div>
                </Popconfirm>
            </>
        );
    }
    if (!start && !finished) {
        if (!recorderStateContext.isRecording) {
            return (
                <Popconfirm
                    title="确定要开始录制?"
                    onConfirm={() => {
                        if (onBeforeStart) {
                            onBeforeStart().then(() => {
                                handleAudioStart();
                            });
                            return;
                        }
                        handleAudioStart();
                    }}
                    getPopupContainer={trigger => (move ? document.body : trigger.parentNode.parentNode)}
                    autoAdjustOverflow={false}
                >
                    <div className={styles.audioButtonContent}>
                        <i className={cn('iconfont iconrecordIcon', styles.startAudioIcon)} />
                        <span style={{ fontSize: 16 }}>开始录音</span>
                    </div>
                </Popconfirm>
            );
        }
        // 下面这个是专供录音互斥用的，莫怪。。。
        return (
            <div
                className={styles.audioButtonContent}
                onClick={() => {
                    message.error('当前正在录音，完成后可开启此沟通录音');
                }}
            >
                <i className={cn('iconfont iconrecordIcon', styles.startAudioIcon)} />
                <span style={{ fontSize: 16 }}>开始录音</span>
            </div>
        );
    }
    if (!start && finished) {
        return (
            <div className={styles.audioButtonContent}>
                <i className={cn('iconfont iconrecordIcon', styles.startAudioIcon)} />
                <span style={{ fontSize: 16 }}>{time}</span>
            </div>
        );
    }
    return null;
};

let RecordButtonContent = props => {
    const {
        start = false,
        finished = false,
        move = false,
        loading = false,
        recordStatusMsg,
        isGuide = false,
        queryLoading,
        guideMsg
    } = props;
    const guideRef = useRef();
    const userCode = useMemo(() => {
        const user = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : {};
        return user?.userCode;
    }, []);
    const handleShowGuide = useCallback(() => {
        localStorage.setItem(`interview_guide_${userCode}`, 'true');
    }, []);
    useEffect(() => {
        const guided = localStorage.getItem(`interview_guide_${userCode}`);
        if (!queryLoading && isGuide && !guided) {
            guideRef.current.setVisible(true);
        }
    }, [queryLoading]);
    return (
        <Spin spinning={loading}>
            <div className={styles.startAudioButtonWrap}>
                {!move && (
                    <Popconfirm
                        ref={guideRef}
                        autoAdjustOverflow={false}
                        overlayClassName={styles.guideWrap}
                        title={guideMsg}
                        cancelText={null}
                        okType="link"
                        icon={null}
                        okText="我知道了"
                        getPopupContainer={trigger => trigger.parentNode}
                        onVisibleChange={visible => {
                            if (visible) handleShowGuide();
                        }}
                    >
                        <div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }} />
                    </Popconfirm>
                )}
                <div
                    className={cn(styles.startAudioButton, {
                        [styles.startAudioButtonStatic]: !move,
                        [styles.startAudioButtonHover]: !start && !finished
                    })}
                    style={{ pointerEvents: recordStatusMsg ? 'none' : 'auto' }}
                >
                    {renderButton({ ...props })}
                </div>
            </div>
        </Spin>
    );
};

RecordButtonContent = memo(RecordButtonContent);

/**
 * 开始录音组件
 *
 * @param { 滚动容器下层级的Ref  } scrollWrapRef
 * @param { 是否可录音方法 } getRecordState
 * @param { 录音开始执行的回调 } onChangeRecordState
 * @param { 函数组件传入的Ref } cRef
 */
const NoHoverReorderButton = props => {
    const recorderStateContext = useContext(RecorderStateContext);
    usePreventUnload();
    const {
        scrollWrapRef,
        getRecordState = () => false,
        onChangeRecordState = () => {}, // 阻止hover
        cRef,
        hintList = {},
        ...rest
    } = props;
    const [uploadFile] = useUploadOss();
    const [isStart, setIsStart] = useState(false);
    const isStartRef = useRef(false);
    const [isFinished, setIsFinished] = useState(false);
    const [currentTime, setCurrentTime] = useState('00:00:00');
    const [audioLoading, setAudioLoading] = useState(false);
    const buttonRef = useRef();
    const [recordTimeInfo] = useState({});
    const recRef = useRef();
    // tab-scroll-context

    const handleAudioUpload = async () => {
        try {
            setAudioLoading(true);
            const blob = recRef.current.getBlob();
            const file = new window.File([blob], `${+new Date()}.mp3`, { type: blob.type });
            const result = await uploadFile(file);
            setAudioLoading(false);
            return result;
        } catch (e) {
            setAudioLoading(false);
            return '';
        }
    };
    const handleAudioStop = () =>
        new Promise((resolve, reject) => {
            clearInterval(timer);
            recRef.current.recStop(resolve, reject);
        })
            .then(() => {
                recordTimeInfo.endTime = new Date().getTime();
                setIsStart(false);
                isStartRef.current = false;
                recorderStateContext.changeState('stop');
                setIsFinished(true);
                onChangeRecordState(2);
                return true;
            })
            .catch(e => {
                console.log(e, '失败的理由');
                return false;
            });
    const handleAudioStart = async () => {
        if (recorderStateContext.isRecording) {
            message.error('当前正在录音，完成后可开启此沟通录音');
            return;
        }
        try {
            if (!isStart && !isFinished) {
                setAudioLoading(true);
                const state = await getRecordState();
                if (!state) {
                    recRef.current.recStart(() => {
                        onChangeRecordState(1);
                        setIsStart(true);
                        isStartRef.current = true;
                        recorderStateContext.changeState('start');
                        recordTimeInfo.startTime = new Date().getTime();
                        clearInterval(timer);
                        timer = setInterval(() => {
                            console.log(recRef.current.getRecDuration());
                            setCurrentTime(recRef.current.getRecDuration());
                        }, 1000);
                    });
                } else {
                    message.error(hintList[state] || '当前已有录音进行中！');
                }
                setAudioLoading(false);
            }
        } catch (e) {
            setAudioLoading(false);
            console.log(e);
        }
    };
    useImperativeHandle(cRef, () => ({
        getRecordInfo: async () => {
            const params = {};
            if (isStart && !isFinished) {
                const state = await handleAudioStop();
                if (state) {
                    params.recordUrl = await handleAudioUpload();
                }
            } else if (isFinished) {
                params.recordUrl = await handleAudioUpload();
            }
            if (params.recordUrl) {
                params.recordTimeInfo = recordTimeInfo;
            }
            return params;
        }
    }));
    // eslint-disable-next-line consistent-return

    useEffect(() => {
        recRef.current = new AudioRecorder();
        recRef.current.recInitialize();
        return () => {
            recRef.current.destroy();
            if (isStartRef.current) {
                recorderStateContext.changeState('stop');
            }
            if (timer) clearInterval(timer);
        };
    }, []);

    // 兜底无法上传的情况，按钮上下载当前录音
    const handleContextMenu = e => {
        e.preventDefault();
        console.log('===开始下载当前录音===');
        const blob = recRef.current.getBlob();
        if (!blob) {
            console.log('===不存在录音===');
            return;
        }
        const link = document.createElement('a');
        const body = document.querySelector('body');

        link.href = window.URL.createObjectURL(blob);
        link.download = '录音.mp3';

        // fix Firefox
        link.style.display = 'none';
        body.appendChild(link);

        link.click();
        body.removeChild(link);

        window.URL.revokeObjectURL(link.href);
    };

    const recordProps = {
        recorderStateContext,
        start: isStart,
        finished: isFinished,
        time: currentTime,
        handleAudioStop,
        handleAudioStart,
        loading: audioLoading,
        ...rest
    };

    return (
        <div ref={buttonRef} onContextMenu={handleContextMenu}>
            <RecordButtonContent {...recordProps} />
        </div>
    );
};

export default memo(NoHoverReorderButton);
